import { PlusOutlined } from '@ant-design/icons';
import { Button, Popconfirm, Space } from 'antd';
import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
import type { ProColumns } from '@ant-design/pro-table';
import ProTable from '@ant-design/pro-table';
import { useModel } from 'umi';
import ModalForm from './ModalForm';
import { NORMAL_CODE } from '@/constants';

const DataTable: React.FC = forwardRef((prod, ref) => {
  //表格dom
  const tableRef = useRef();
  //表单dom
  const formModalRef = useRef();
  const [modalFormVisible, handleModalFormVisible] = useState(false);
  //数据模型
  const menuModel = useModel('admin.menu', (model) => ({
    data: model.data,
    setData: model.setData,
    minTotal: model.minTotal,
    minList: model.minList,
    minLists: model.minLists,
    total: model.total,
    list: model.list,
    lists: model.lists,
    read: model.read,
    create: model.create,
    update: model.update,
    del: model.del,
  }));
  //**********prod分析*************
  //默认搜索参数
  const [searchData, setSearchData] = useState(prod.search ?? {});
  //操作配置数据
  const [operateData, setOperateData] = useState(prod.operate ?? {});
  //操作栏定义
  let operateToolBarRender: React.ReactNode[] | JSX.Element[] = [];
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
  operateData.add && operateToolBarRender.push(<Button
    key="button"
    icon={<PlusOutlined />}
    type="primary"
    onClick={async () => {
      handleModalFormVisible(true);
      menuModel.setData({})
    }}
  >
    新建
  </Button>);
  //  多选
  const [batchData, setbatchData] = useState(operateData.mulChoice ? (operateData?.mulChoice?.batchData ?? []) : []);
  useEffect(() => {
    let abortController = new AbortController();
    if(prod?.operate?.mulChoice?.batchData){
      setbatchData(prod.operate.mulChoice.batchData);
    }
    return () => {
      abortController.abort();
    };
  }, [prod?.operate?.mulChoice?.batchData]);

  let mulChoiceRender = {
    rowSelection: false,
    tableAlertRender: false,
    tableAlertOptionRender: false,
  };
  if (operateData.mulChoice) {
    // 批量选中数据
    if (operateData.mulChoice.rowSelection) {
      mulChoiceRender.rowSelection = {
        selectedRowKeys: batchData.map((item) => item.id),
        onSelect: (record, selected) => {
          let batchArr = [];
          if (selected) {
            // 如果选中,加入selectedRowKeys
            batchArr = Array.from(new Set([...batchData, { id: record.id, name: record.name }]));
          } else {
            // 如果未选中,删除这一项数据
            batchArr = batchData.filter((item) => {
              return item.id !== record.id;
            });
          }
          setbatchData(batchArr);
        },
        onSelectAll: (selected, selectedRows, changeRows) => {
          let batchArr = [];
          const changeData = changeRows.map((item) => { return { id: item.id, name: item.name } });
          if (selected) {
            // 如果选中,加入selectedRowKeys
            batchArr = Array.from(new Set([...batchData, ...changeData]));
          } else {
            // 如果未选中,删除数据
            batchArr = batchData.filter((item) => {
              return changeData.map((item) => item.id).indexOf(item.id) < 0;
            });
          }
          setbatchData(batchArr);
        },
      }
    }
    if (operateData.mulChoice.tableAlertRender) {
      mulChoiceRender.tableAlertRender = ({ selectedRowKeys, selectedRows, onCleanSelected }) => (
        <Space size={24}>
          <span>
            已选 {batchData.length} 项
            <a
              style={{ marginLeft: 8 }}
              onClick={() => {
                setbatchData([]);
              }}
            >
              取消选择
            </a>
          </span>
        </Space>
      )
    }
    if (operateData.mulChoice.tableAlertOptionRender) {
      mulChoiceRender.tableAlertOptionRender = () => {
        const operate = [];
        // eslint-disable-next-line @typescript-eslint/no-unused-expressions
        operateData.mulChoice.batchDelete && operate.push(<Space key='batch_delete' size={16}>
          <a>
            <Popconfirm
              title="是否删除?"
              onConfirm={async () => {
                const ids = batchData.map((item) => item.id).join(',');
                await menuModel.del({ ids });
                setbatchData([]);
                if (tableRef.current) {
                  tableRef.current.reload();
                }
              }}
              okText="是"
              cancelText="否"
            >
              批量删除
            </Popconfirm>
          </a>
        </Space>);
        // eslint-disable-next-line @typescript-eslint/no-unused-expressions
        operateData.mulChoice.batchChoice && operate.push(<Space key='batch_choice' size={16}>
          <a>
            <Popconfirm
              title="是否选择?"
              onConfirm={async () => {
                await operateData.mulChoice.batchChoiseCall(batchData);
              }}
              okText="是"
              cancelText="否"
            >
              批量选择
            </Popconfirm>
          </a>
        </Space>);
        return operate;
      }
    }
  }
  //操作列定义
  const operateRender = (text, record, _, action) => {
    //操作列定义
    let operateRender = [];
    // eslint-disable-next-line @typescript-eslint/no-unused-expressions
    operateData.edit && operateRender.push(<a
      key="edit"
      onClick={async () => {
        handleModalFormVisible(true)
        await menuModel.read({ id: record.id });
      }}
    >
      编辑
    </a>);
    // eslint-disable-next-line @typescript-eslint/no-unused-expressions
    operateData.delete && operateRender.push(<a key="delete">
      <Popconfirm
        title="是否删除?"
        onConfirm={async () => {
          const ids = record.id;
          await menuModel.del({ ids });
          const idData = batchData.filter((item) => {
            return item.id !== record.id;
          });
          setbatchData(idData);
          if (tableRef.current) {
            tableRef.current.reload();
          }
        }}
        okText="是"
        cancelText="否"
      >
        删除
      </Popconfirm>
    </a>);
    //  单选
    // eslint-disable-next-line @typescript-eslint/no-unused-expressions
    operateData.oneChoice && operateRender.push(<a
      key="oneChoice"
      onClick={async () => {
        await operateData.oneChoiceCall({ id: record.id, name: record.name })
      }}
    >
      选择
    </a>);
    return operateRender;
  }
  //列配置数据
  const [columnData, setColumnData] = useState(prod.columns ?? []);
  let columns: ProColumns[] = [
    {
      title: '标识',
      key: 'mark',
      dataIndex: 'mark',
      fixed: 'left',
    },
    {
      title: '菜单名',
      key: 'name',
      dataIndex: 'name',
      ellipsis: true,
    },
    {
      title: '排序',
      key: 'sort',
      dataIndex: 'sort',
      ellipsis: true,
      hideInSearch: true,
    },
    {
      title: '备注',
      key: 'remark',
      dataIndex: 'remark',
      ellipsis: true,
      hideInSearch: true,
    },
    {
      title: '创建时间',
      key: 'created_at',
      dataIndex: 'created_at',
      valueType: 'dateRange',
      render: (text, record) => {
        return <div>{record?.created_at}</div>;
      },
    },
    {
      title: '操作',
      key: 'operate',
      valueType: 'option',
      align: 'center',
      fixed: 'right',
      render: operateRender,
    },
  ];
  columns = columns.filter((item) => {
    return columnData.indexOf(item.key) > -1;
  })
  //表格数据源
  const [dataSource, setDataSource] = useState([]);
  useEffect(() => {
    //防止组件卸载报错
    let abortController = new AbortController();
    switch (prod.mode) {
      case 2:
        setDataSource(menuModel.minList);
        break;
      case 1:
      default:
        setDataSource(menuModel.list);
        break;
    }
    return () => {
      abortController.abort();
    };
  }, [prod.mode, menuModel.list, menuModel.minList]);

  // 暴露给父组件的方法
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
  useImperativeHandle(ref, () => ({
    reload: () => {
      if (tableRef.current) {
        tableRef.current.reload();
      }
    },
  }))
  return (
    <>
      <ProTable
        actionRef={tableRef}
        rowKey="id"
        scroll={{ x: 1600 }}
        columns={columns}
        //多选
        rowSelection={mulChoiceRender.rowSelection}
        tableAlertRender={mulChoiceRender.tableAlertRender}
        tableAlertOptionRender={mulChoiceRender.tableAlertOptionRender}

        search={{
          labelWidth: 'auto',
        }}
        pagination={{
          pageSize: 10,
        }}
        toolBarRender={() => operateToolBarRender}
        // 数据源在model管理，因此这边需要dataSource配合
        params={searchData}
        request={async (params, sort, filter) => {
          switch (prod.mode) {
            case 1:
              await menuModel.lists({
                ...params,
                search_page: params.current,
                search_limit: params.pageSize,
                created_begin: params.created_at ? params.created_at[0] : '',
                created_end: params.created_at ? params.created_at[1] : '',
              });
              return {
                data: [],
                // success 请返回 true，
                // 不然 table 会停止解析数据，即使有数据
                success: true,
                // 不传会使用 data 的长度，如果是分页一定要传
                total: menuModel.total,
              };
              break;
            case 2:
            default:
              await menuModel.minLists({
                ...params,
                search_page: params.current,
                search_limit: params.pageSize,
                created_begin: params.created_at ? params.created_at[0] : '',
                created_end: params.created_at ? params.created_at[1] : '',
              });
              return {
                data: [],
                // success 请返回 true，
                // 不然 table 会停止解析数据，即使有数据
                success: true,
                // 不传会使用 data 的长度，如果是分页一定要传
                total: menuModel.minTotal,
              };
              break;
          }
        }}
        dataSource={dataSource}
      />
      <ModalForm
        ref={formModalRef}
        modalVisible={modalFormVisible}
        onSubmit={async (res) => {
          if (res.code === NORMAL_CODE) {
            handleModalFormVisible(false);
            if (tableRef.current) {
              tableRef.current.reload();
            }
          }
        }}
        onCancel={() => {
          handleModalFormVisible(false);
        }}
      />
    </>
  );
});

export default DataTable;
